package hh.util.bean.codegen;

import hh.util.CommonUtil;
import hh.util.StringUtil;
import hh.util.bean.ClassUtil;
import hh.compile.CompileUtil;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author huanghuai
 * @date 2020/10/27
 */
public class DefaultCopyProxyFactory implements CopyProxyFactory {
    static final AtomicInteger index = new AtomicInteger(0);
    static final String pkg = "hh.util.beanutil.codegen";
    static final String classNamePrefix = "CGFull";
    static final String creatorCode = "package " + pkg + ";" +
            "import ?;" +
            "import ?;" +
            "import " + JavaBeanCreator.class.getName() + ";" +
            "public final class ? implements " + FullCodeGenerateCopyProxy.class.getName() + "<?>{" +
            "JavaBeanCreator creator;" +
            "@Override public void setJavaBeanCreator(JavaBeanCreator creator){this.creator=creator;}" +
            "@Override public Object copy(? source){? dest=(?)creator.newObject(); ? return dest;}" +
            "}";


    @Override
    public FullCodeGenerateCopyProxy getCopyProxy(Class sourceClass, Class destClass, Field[] destFields) {
        String className = classNamePrefix + index.getAndIncrement();
        String fullClassName = pkg + "." + className;
        StringBuilder copyCode = new StringBuilder(1024);
        for (Field field : destFields) {
            copyCode.append(StringUtil.formatQ("dest.?(source.?());", ClassUtil.setterMethodName(field),
                    ClassUtil.getterMethodName(field)));
        }

        String sourceCode = StringUtil.formatQ(creatorCode, sourceClass.getName(), destClass.getName(), className,
                sourceClass.getSimpleName(), sourceClass.getSimpleName(), destClass.getSimpleName(), destClass.getSimpleName(), copyCode);
        try {
            return (FullCodeGenerateCopyProxy) CompileUtil.compile(fullClassName, sourceCode).newInstance();
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }
}


